package main

import (
	"bytes"
	"flag"
	"fmt"
	"net/http"
	"strconv"
	"strings"

	"github.com/gin-gonic/gin"
)

type P struct {
	AgentUri string
	Port     int
}

var p = &P{}

func main() {
	// 解析启动参数
	if !StartParams() {
		return
	}

	r := gin.New()
	r.Use(gin.Recovery())
	// filepath模式，拦截所有请求
	r.GET("/*filepath", ReceiveGet)
	r.POST("/*filepath", RequestPost)

	fmt.Printf("启动监听 端口[%v], 代理地址[%v]\n", p.Port, p.AgentUri)
	r.Run(":" + strconv.Itoa(p.Port))
}

// 起动参数
func StartParams() bool {
	aUri := flag.String("url", "http://baidu.com", "目标代理地址，示例: http://baidu.com")
	port := flag.Int("port", 80, "监听端口，示例：80")
	flag.Parse()

	p.AgentUri = *aUri
	p.Port = *port

	if p.AgentUri == "" || p.Port == 0 {
		flag.PrintDefaults()
		return false
	}

	return true
}

// 接收get请求
func ReceiveGet(c *gin.Context) {
	response, err := http.Get(p.AgentUri + c.Request.URL.RequestURI())
	if err != nil {
		c.AbortWithError(http.StatusServiceUnavailable, err)
		return
	}
	reader := response.Body
	contentLenth := response.ContentLength
	contentType := response.Header.Get("Content-Type")
	c.DataFromReader(response.StatusCode, contentLenth, contentType, reader, map[string]string{})
}

// 接收post请求
func RequestPost(c *gin.Context) {
	fmt.Println(p.AgentUri + c.Request.URL.RequestURI())
	fmt.Println(c.Request.Header.Get("Content-Type"))
	buf := new(bytes.Buffer)
	buf.ReadFrom(c.Request.Body)
	response, err := http.Post(
		p.AgentUri+c.Request.URL.RequestURI(),
		c.Request.Header.Get("Content-Type"),
		strings.NewReader(buf.String()),
	)
	if err != nil {
		c.AbortWithError(http.StatusServiceUnavailable, err)
		return
	}
	reader := response.Body
	contentLenth := response.ContentLength
	contentType := response.Header.Get("Content-Type")

	c.DataFromReader(response.StatusCode, contentLenth, contentType, reader, map[string]string{})
}
